﻿using System;
using System.Runtime.Serialization;
using CID.Domain.Infrastructure;

namespace CID.Execution.Support.Information
{
    [DataContract]
    public class ParameterValueInfo
    {
        /// <summary>
        /// Enumerates the system reserved names for the additional parameters
        /// </summary>
        /// <remarks>This class needs to be synchronized with the values declared in <see cref="Parameter.ReservedNames"/> </remarks>
        public static class ReservedParameterNames
        {
            public const string ComponentName = Parameter.ReservedNames.ComponentName;
            public const string PackageComment = Parameter.ReservedNames.PackageComment;
            public const string PackagePath = Parameter.ReservedNames.PackagePath;
            public const string ReleaseName = Parameter.ReservedNames.ReleaseName;
            public const string VersionName = Parameter.ReservedNames.VersionName;
            public const string TargetServerAddress = Parameter.ReservedNames.TargetServerAddress;
            public const string TargetServersAddresses = Parameter.ReservedNames.TargetServersAddresses;
        }

        public static ParameterValueInfo CreateAdditionalParameterValue(string name, string value)
        {
            return new ParameterValueInfo(name, value);
        }

        private ParameterValueInfo(string name, string value)
        {
            ParameterName = name;
            ParameterType = ParameterType.String;
            StringValue = value;
        }

        internal ParameterValueInfo() { }

        public ParameterValueInfo(IParameterValue parameterValue)
        {
            ParameterId = parameterValue.Parameter.Id;
            ParameterName = parameterValue.Parameter.Name;
            ParameterType = parameterValue.Parameter.Type;
            switch (ParameterType)
            {
                case ParameterType.String: StringValue = parameterValue.StringValue; break;
                case ParameterType.Integer: IntegerValue = parameterValue.IntegerValue; break;
                case ParameterType.Decimal: DecimalValue = parameterValue.DecimalValue; break;
                case ParameterType.Boolean: BooleanValue = parameterValue.BooleanValue; break;
                case ParameterType.DateTime: DateTimeValue = parameterValue.DateTimeValue; break;
                case ParameterType.UniqueIdentifier: UniqueIdentifierValue = parameterValue.UniqueIdentifierValue; break;
                case ParameterType.Xml: XmlValue = parameterValue.XmlValue.OuterXml; break;
            }
        }

        [DataMember]
        public int ParameterId { get; set; }

        [DataMember]
        public string ParameterName { get; set; }

        [DataMember]
        public ParameterType ParameterType { get; set; }

        [DataMember]
        public bool? BooleanValue { get; set; }

        [DataMember]
        public DateTime? DateTimeValue { get; set; }

        [DataMember]
        public decimal? DecimalValue { get; set; }

        [DataMember]
        public int? IntegerValue { get; set; }

        [DataMember]
        public string StringValue { get; set; }

        [DataMember]
        public Guid? UniqueIdentifierValue { get; set; }
        
        [DataMember]
        public string XmlValue { get; set; }

        internal ParameterValueInfo Clone()
        {
            return new ParameterValueInfo()
            {
                ParameterId = ParameterId,
                ParameterName = ParameterName,
                ParameterType = ParameterType,
                BooleanValue = BooleanValue,
                DateTimeValue = DateTimeValue,
                DecimalValue = DecimalValue,
                IntegerValue = IntegerValue,
                StringValue = StringValue,
                UniqueIdentifierValue = UniqueIdentifierValue,
                XmlValue = XmlValue
            };
        }
    }
}
